package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.redis.AccessVo;
import cn.wolfcode.luowowo.redis.RedisKey;
import cn.wolfcode.luowowo.redis.srevice.IUserRedisSrevice;
import cn.wolfcode.luowowo.repository.UserInfoRepository;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.AssertUtil;
import cn.wolfcode.luowowo.util.Consts;
import cn.wolfcode.luowowo.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import java.awt.print.Pageable;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserInfoServiceImpl implements IUserInfoService {
    @Autowired
    private UserInfoRepository repository;
    
    @Autowired
    private IUserRedisSrevice userRedisSrevice;
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Override
    public UserInfo get(String id) {
        Optional<UserInfo> byId = repository.findById(id);
        
        //判断是否为空,不为空就返回原有值,为空就返回null
        if (byId.isPresent()) {
            return byId.get();
        }
        return null;
    }
    
    //查询号码唯一性
    @Override
    public boolean checkPhone(String phone) {
        //通过号码去数据库进行匹配 返回的值是不是空来进行判断唯一性
        UserInfo u = repository.findByPhone(phone);
        /*如果值不为空 就是true 就是有值 就是号码被注册了*/
        return u != null;
    }
    
    //生成验证码
    @Override
    public void sendVerifyCode(String phone, String smsUrl, String smsAppkey, String smsSignature) {
        //生成一个uuid 取它前面四个数 然后将其中的-替换掉
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4);
        
        
        //模拟发送短信 限制字数在70
        StringBuilder builder = new StringBuilder(70);
        //将短信拼接起来
//        StringBuilder append = builder.append("您好,您现在正在注册我们的Luowowo账号,这是您的验证码:'").append(uuid)
//                .append("',请妥善保管,不要交给其他人.验证码将于").append(Consts.VERIFY_CODE_VAI_TIME)
//                .append("分钟后失效,请尽快使用");
        // String s = "\\u3010\\u9aa1\\u7a9d\\u7a9d\\u3011,您好,您现在正在注册我们的Luowowo账号,这是您的验证码:";
        StringBuilder append = builder.append("\\\\u3010\\\\u9aa1\\\\u7a9d\\\\u7a9d\\\\u3011")
                .append("您好,您现在正在注册我们的Luowowo账号,这是您的验证码:");
        /*发送http请求 */
        RestTemplate template = new RestTemplate();
        /*请求的方法可以拼接起来*/
        String ret = template.getForObject(smsUrl, String.class, phone, append.toString(), uuid, smsAppkey);
        //假装发送了
        System.err.println("验证码为;==================>>>" + uuid + "<<=====================");
        System.out.println(ret);
        //如果返回的信息中没有正确的信息,就报错
       /* if (!ret.contains("查询成功")) {
            throw new LogicException("短信发送失败!");
        }*/
        
        
        //将验证码和手机号存入缓存中
        userRedisSrevice.setVerifyCode(phone, uuid);
    }
    
    @Override
    public void setUserInfo(String verifyCode, String phone, String nickname, String password, String rpassword) {
        /*手机号码的格式判断*/
        AssertUtil.phoneFormat(phone, "号码格式有误,请重新输入!");
        
        /*首先对用户的数据进行判空*/
        AssertUtil.hasLength(verifyCode, "验证码不能为空");
        AssertUtil.hasLength(phone, "手机号不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "第二个密码不能为空");
        
        
        /*判断两次密码是否都一致 也可以使用工具类进行判断抛异常*/
        AssertUtil.unanimous(password, rpassword);
        
        /*进行验证码的正确性判断,使用redis进行查询判断*/
        AssertUtil.verByRedis(userRedisSrevice.getVerifyCode(verifyCode, phone), "验证码有误,请重新确认!");
        
        
        /*上面都没有问题的话就进行数据的存储*/
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        
        userInfo.setPassword(DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8)));//MD5的加密操作
        userInfo.setPhone(phone);
        userInfo.setEmail("");//防止空字段的出现
        userInfo.setCity("");
        userInfo.setGender(0);
        userInfo.setLevel(1);
        userInfo.setCity("");
        userInfo.setHeadImgUrl("");
        userInfo.setInfo("");
        userInfo.setState(0);
        repository.save(userInfo);
    }
    
    //查询用户的信息
    @Override
    public UserInfo getUserByUsernameAndPassword(String username, String password) {
        AssertUtil.hasLength(username, "用户名不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        //为密码加密
        String MD5password = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        //在mongodb里面查询的规范语句
        UserInfo user = repository.findByPhoneAndPassword(username, MD5password);
        /*判断用户信息是否存在,为空报异常*/
        if (user != null) {
            //将用户的密码设空,防止数据泄露的问题
            user.setPassword(null);
            return user;
        } else {
            throw new LogicException("用户名或密码错误,请确认后输入!");
        }
    }
    
    @Override
    public List<UserInfo> findByCity(String name) {
        return repository.findByCity(name);
    }
    
    @Override
    public List<UserInfo> list() {
        return repository.findAll();
    }
    
    
}
